package com.ruoyi.dm.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.CollectFileTypeConstants;
import com.ruoyi.common.enums.CollectFileStatusEnum;
import com.ruoyi.common.exception.DataRepeatException;
import com.ruoyi.common.utils.biz.BizModule;
import com.ruoyi.common.utils.biz.PathUtil;
import com.ruoyi.dm.component.AnalysisStrategyManager;
import com.ruoyi.dm.component.DataStrategyManager;
import com.ruoyi.dm.domain.CollectEstimateVO;
import com.ruoyi.dm.domain.CollectQueryParam;
import com.ruoyi.dm.domain.GroundCollectVO;
import com.ruoyi.dm.domain.po.EstimateRecordPO;
import com.ruoyi.dm.domain.po.GroundCollectRecordPO;
import com.ruoyi.dm.mapper.GroundCollectRecordMapper;
import com.ruoyi.dm.service.IEstimateRecordService;
import com.ruoyi.dm.service.IGroundCollectRecordService;
import com.ruoyi.utils.TranferUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class GroundCollectRecordServiceImpl extends ServiceImpl<GroundCollectRecordMapper, GroundCollectRecordPO> implements IGroundCollectRecordService {
    @Autowired
    private IGroundCollectRecordService recordService;


    @Autowired
    private AnalysisStrategyManager analysisStrategyManager;

    @Autowired
    private DataStrategyManager dataStrategyManager;

    @Autowired
    private IEstimateRecordService estimateRecordService;

    @Override
    public IPage query(CollectQueryParam queryParam) {

        LambdaQueryWrapper<GroundCollectRecordPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasLength(queryParam.getFileName()),GroundCollectRecordPO::getFileName,queryParam.getFileName());
        queryWrapper.eq(StringUtils.hasLength(queryParam.getStation()),GroundCollectRecordPO::getStation,queryParam.getStation());
        queryWrapper.eq(StringUtils.hasLength(queryParam.getStatus()), GroundCollectRecordPO::getStatus,queryParam.getStatus());
        queryWrapper.eq(StringUtils.hasLength(queryParam.getFileType()), GroundCollectRecordPO::getFileType,queryParam.getFileType());
        queryWrapper.orderByDesc(GroundCollectRecordPO::getFileDate);
        queryWrapper.between(null != queryParam.getStartTime() && null!= queryParam.getEndTime(),GroundCollectRecordPO::getFileDate,queryParam.getStartTime(),queryParam.getEndTime());
        IPage page = recordService.page(queryParam.page(), queryWrapper);
        List<GroundCollectVO> objects = new ArrayList<>();
        for (Object groundCollectRecordPO : page.getRecords()) {
            GroundCollectRecordPO po = (GroundCollectRecordPO) groundCollectRecordPO;
            GroundCollectVO vo = TranferUtils.tranferGroundRecordPO(po);
            objects.add(vo);
        }
        page.setRecords(objects);
        return page;
    }

    @Override
    public List<String> uploadFile(MultipartFile[] files, String station, String type) throws DataRepeatException {

        //单个文件,如果重复,直接抛异常
        if (files.length==1) {
            String filename = files[0].getOriginalFilename();
            int num = this.checkRepeat(filename);
            if (num>0) {
                //存在 不处理
                throw new DataRepeatException();
            }
        }

        List<GroundCollectRecordPO> list = new ArrayList<>(files.length);
        Date now = new Date();
        String midPath = "/origin/wind/"+station;
        if (CollectFileTypeConstants.TYPE_RADAR.equals(type)) {

        }else if (CollectFileTypeConstants.TYPE_RADIO.equals(type)) {
            //无线电探空存储路径
            midPath = "/origin/wind/sounding";
        }
        List<String> resList = new ArrayList<>();
        for (MultipartFile file : files) {

            String filename = file.getOriginalFilename();
            int num = this.checkRepeat(filename);
            if (num>0) {
                //存在 不处理
                resList.add(filename);
                continue;
            }

            GroundCollectRecordPO po = new GroundCollectRecordPO();
            po.setFileName(filename);
            po.setFileType(type);
            po.setStation(station);
            po.setFileSize(file.getSize());
            po.setUploadTime(now);
            po.setFilePath(midPath);
            po.setStatus(CollectFileStatusEnum.FILE_SUCC.getCode());
            try {
                //通过filename 获取 信息
                String fullPath = PathUtil.outputModuleDir(BizModule.COLLECT)+midPath;
                File parentPath = new File(fullPath);
                if (!parentPath.exists()) {
                    parentPath.mkdirs();
                }
                File path = new File(fullPath, filename);
                file.transferTo(path);
                log.info("文件:{} 上传完成",path );
                //选择数据策略,并进行相应的的特殊化处理
                dataStrategyManager.switchStrategy(type,station,null).makeupPo(po);
            }catch (Exception e) {
                log.error("文件保存异常",e);
                po.setStatus(CollectFileStatusEnum.FILE_ERROR.getCode());
                po.setFileDesc("保存异常，"+e.getMessage());
            }

            list.add(po);
        }
        //保存到数据库
        recordService.saveBatch(list);
        //for (GroundCollectRecordPO po : list) {
        //    analysisStrategyManager.analysisGround(po, null);
        //}
        return resList;
    }

    @Override
    public boolean delFile(Long id) {
        LambdaQueryWrapper<GroundCollectRecordPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(GroundCollectRecordPO::getFilePath,GroundCollectRecordPO::getFileName);
        wrapper.eq(GroundCollectRecordPO::getId,id);
        GroundCollectRecordPO po = recordService.getOne(wrapper);
        String fullPath = PathUtil.outputModuleDir(BizModule.COLLECT)+po.getFilePath()+"/"+ po.getFileName();
        new File(fullPath).delete();
        return recordService.removeById(id);
    }

    @Override
    public boolean delBatch(Long[] delParam) {
        LambdaQueryWrapper<GroundCollectRecordPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(GroundCollectRecordPO::getId,delParam);
        queryWrapper.select(GroundCollectRecordPO::getFilePath,GroundCollectRecordPO::getFileName);
        List<GroundCollectRecordPO> pos = recordService.list(queryWrapper);
        if (null != pos) {
            for (GroundCollectRecordPO po : pos) {
                String fullPath = PathUtil.outputModuleDir(BizModule.COLLECT)+po.getFilePath()+"/"+ po.getFileName();
                new File(fullPath).delete();
            }
        }

        return recordService.remove(queryWrapper);
    }

    @Override
    public String download(Long id) {
        LambdaQueryWrapper<GroundCollectRecordPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(GroundCollectRecordPO::getFilePath,GroundCollectRecordPO::getFileName);
        wrapper.eq(GroundCollectRecordPO::getId,id);
        GroundCollectRecordPO po = recordService.getOne(wrapper);
        String fullPath = PathUtil.outputModuleDir(BizModule.COLLECT);
        return fullPath+po.getFilePath()+"/"+ po.getFileName();
    }

    @Override
    public String downloadBatch(Long[] ids) {
        LambdaQueryWrapper<GroundCollectRecordPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(GroundCollectRecordPO::getId,ids);
        List<GroundCollectRecordPO> list = recordService.list(queryWrapper);
        String path = PathUtil.tmpModuleDir(BizModule.COLLECT)+"/"+ DateUtil.format(new Date(),"yyyyMMddHHmmss")+".zip";
        if (CollectionUtil.isNotEmpty(list)) {
            File[] toZipArr = new File[list.size()];
            for (int i = 0; i < list.size(); i++) {
                String fullPath = PathUtil.outputModuleDir(BizModule.COLLECT)+list.get(i).getFilePath()+"/"+list.get(i).getFileName();
                toZipArr[i] = new File(fullPath);
            }
            ZipUtil.zip(new File(path), false, toZipArr);
        }
        return path;
    }

    @Override
    public boolean analysis(String fileType, Integer startYear, Integer endYear, String method, Date startTime, Date endTime) {
        if (CollectFileTypeConstants.TYPE_RADAR.equals(fileType)) {
            List<String> stations = ListUtil.of("MH", "BATH");
            for (String station : stations) {
                LambdaQueryWrapper<GroundCollectRecordPO> wrapper = new LambdaQueryWrapper<>();
                wrapper.select(GroundCollectRecordPO::getFilePath, GroundCollectRecordPO::getFileName, GroundCollectRecordPO::getFileType, GroundCollectRecordPO::getStation);
                wrapper.eq(GroundCollectRecordPO::getFileType, CollectFileTypeConstants.TYPE_RADAR);
                wrapper.eq(GroundCollectRecordPO::getStation,station);
                wrapper.last("limit 1");
                //雷达 有多个
                GroundCollectRecordPO po = recordService.getOne(wrapper);
                for (int i = startYear; i <= endYear ; i++) {
                    analysisStrategyManager.analysisGroundRadar(po, i, method);
                }
            }

        }else if (CollectFileTypeConstants.TYPE_RADIO.equals(fileType)) {
            LambdaQueryWrapper<GroundCollectRecordPO> wrapper = new LambdaQueryWrapper<>();
            wrapper.select(GroundCollectRecordPO::getFilePath, GroundCollectRecordPO::getFileName, GroundCollectRecordPO::getFileType, GroundCollectRecordPO::getStation);
            wrapper.eq(GroundCollectRecordPO::getFileType, fileType);
            wrapper.last("limit 1");
            GroundCollectRecordPO po = recordService.getOne(wrapper);
            String yyyyMMddHH = DateUtil.format(startTime, "yyyyMMddHH");
            analysisStrategyManager.analysisGroundRadio(po, yyyyMMddHH, method);
        }
        return true;
    }


    @Override
    public CollectEstimateVO lookRes(String fileType, Date startTime, Date endTime) throws Exception {
        LambdaQueryWrapper<EstimateRecordPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(EstimateRecordPO::getTotal,EstimateRecordPO::getErrorNum);
        wrapper.eq(EstimateRecordPO::getFileType,fileType);
        wrapper.between(EstimateRecordPO::getDataTime,startTime,endTime);
        List<EstimateRecordPO> ls = estimateRecordService.list(wrapper);
        if (null != ls ) {
            Integer total = 0;
            Integer errorNum = 0;
            for (EstimateRecordPO l : ls) {
                total+=l.getTotal();
                errorNum+=l.getErrorNum();
            }
            CollectEstimateVO collectEstimateVO = new CollectEstimateVO();
            collectEstimateVO.setToal(total);
            collectEstimateVO.setError(errorNum);
            return collectEstimateVO;
        }else {
            return null;
        }
    }

    @Override
    public String lookDetailRes(String fileType, Date startTime,Date endTime) throws Exception {
        LambdaQueryWrapper<EstimateRecordPO> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(EstimateRecordPO::getFilePath);
        wrapper.eq(EstimateRecordPO::getFileType,fileType);
        wrapper.between(EstimateRecordPO::getDataTime,startTime,endTime);
        List<EstimateRecordPO> list = estimateRecordService.list(wrapper);

        if (null != list ) {
            StringBuilder sb = new StringBuilder();
                for (EstimateRecordPO po : list) {
                    String filePath = po.getFilePath();
                    if (new File(filePath).exists() ) {
                        sb.append(FileUtil.readString(filePath, Charset.forName("UTF-8")));
                        sb.append("\n");
                    }
                }
            return sb.toString();
        }else {
            throw  new Exception("数据不存在或解析异常");
        }
    }


    @Override
    public int checkRepeat(String filename) {
        return this.getBaseMapper().selectRepeat(filename);
    }
}
